﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Crm.Sdk.Data.Services;
using System.Windows.Browser;
using System.Data.Services.Client;
using System.IO;
using System.Xml.Linq;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;
using System.Collections;


namespace SLExportUserViews
{
    public partial class MainPage : UserControl
    {
        private String _serverUrl;
        private BasicContext _context;
        private DataServiceCollection<UserQuery> _UsersQueriesExport;
        private List<UserQuery> _UsersQueriesImport;
        private SaveFileDialog _ExportDiag;
        private OpenFileDialog _ImportDiag;
        private XDocument xdocImport;

        public MainPage()
        {
            InitializeComponent();
            //Set tab1's tab strip to run along the bottom of the
            //TabControl, rather than the top.
            tab1.TabStripPlacement = Dock.Top;

            //Get the ServerUrl (ServerUrl is formatted differently OnPremise than OnLine)
            _serverUrl = Microsoft.Crm.Sdk.Samples.ServerUtility.GetServerUrl();

            if (!String.IsNullOrEmpty(_serverUrl))
            {
                //Setup Context
                _context = new BasicContext(new Uri(
                    String.Format("{0}/xrmservices/2011/organizationdata.svc/", _serverUrl), UriKind.Absolute));

                //This is important because if the entity has new attributes added the code will fail.
                _context.IgnoreMissingProperties = true;

                AddColumns(dgUserQueriesExport);
                AddColumns(dgUserQueriesImport);
                LoadExistingUserQueries();
            }
            else
            {
                MessageBox.Show("Unable to access server url. Launch this Silverlight " +
                        "Web Resource from a CRM Form OR host it in a valid " +
                        "HTML Web Resource with a " +
                        "<script src='../ClientGlobalContext.js.aspx' " +
                        "type='text/javascript'></script>");
            }

            this._ExportDiag = new SaveFileDialog();

            try
            {
                _ExportDiag.DefaultExt = "*.xml";
                _ExportDiag.Filter = "Text Files|*.txt|XML Files|*.xml";
                _ExportDiag.FilterIndex = 2;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fail to configure Save file Dialog: " + ex.ToString());
            }

            _UsersQueriesImport = new List<UserQuery>();
        }

        private void InitImportDialog()
        {
            this._ImportDiag = new OpenFileDialog();
            try
            {
                _ImportDiag.Filter = "Text Files|*.txt|XML Files|*.xml";
                _ImportDiag.FilterIndex = 2;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fail to configure Open file Dialog: " + ex.ToString());
            }
        }
        public void LoadExistingUserQueries()
        {
            var query = _context.UserQuerySet.Where(u => u.StateCode.Value == 0);
            _UsersQueriesExport = new DataServiceCollection<UserQuery>();
            _UsersQueriesExport.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(usersQueriesExport_LoadCompleted);
            _UsersQueriesExport.LoadAsync(query);
        }

        public void usersQueriesExport_LoadCompleted(object sender, LoadCompletedEventArgs e)
        {
            //dgUserQueries.ItemsSource = _UsersQueries.Select(v => new { Name = v.Name, Description = v.Description, UserQueryId = v.UserQueryId, FetchXml = v.FetchXml, ColumnSetXml = v.ColumnSetXml });
            dgUserQueriesExport.ItemsSource = _UsersQueriesExport;
        }

        public DataGridTextColumn CreateextColumn(string header, string dataField)
        {
            DataGridTextColumn col = new DataGridTextColumn();
            col.Header = header;
            col.Binding = new System.Windows.Data.Binding(dataField);
            return col;
        }

        private void AddColumns(DataGrid dg)
        {
            dg.Columns.Clear();
            //dgUserQueries.Columns.Add(CreateextColumn("ID", "UserQueryId"));
            dg.Columns.Add(CreateextColumn("Name", "Name"));
            dg.Columns.Add(CreateextColumn("Description", "Description"));
            dg.Columns.Add(CreateextColumn("ReturnedTypeCode", "ReturnedTypeCode"));
            dg.Columns.Add(CreateextColumn("FetchXml", "FetchXml"));
        }

        private void btnExport_Click(object sender, RoutedEventArgs e)
        {
            bool? res = this._ExportDiag.ShowDialog();
            if (res == true)
            {
                try
                {
                    IEnumerable selectedViews = dgUserQueriesExport.ItemsSource;

                    XElement userQuerisXML = new XElement("UserQueries");
                    foreach (var a in selectedViews)
                    {
                        UserQuery s = a as UserQuery;
                        if (s != null)
                        {
                            userQuerisXML.Add(new XElement("UserQuery",
                                new XElement("Name", s.Name),
                                new XElement("Description", s.Description),
                                new XElement("FetchXml", s.FetchXml),
                                new XElement("ColumnSetXml", s.ColumnSetXml),
                                new XElement("AdvancedGroupBy", s.AdvancedGroupBy),
                                new XElement("ConditionalFormatting", s.ConditionalFormatting),
                                new XElement("LayoutXml", s.LayoutXml),
                                new XElement("QueryType", s.QueryType),
                                new XElement("ReturnedTypeCode", s.ReturnedTypeCode),
                                new XElement("VersionNumber", s.VersionNumber)
                                ));
                        }
                    }
                    XDocument myXml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XComment("Microsoft Dynamics Crm 2011 User Views"), userQuerisXML);

                    using (Stream fs = (Stream)_ExportDiag.OpenFile())
                    {
                        myXml.Save(fs);
                        // Logic to write the XML file   
                        //XmlSerializer xs = new XmlSerializer(typeof(XDocument));  
                        //StreamWriter writer = new StreamWriter(fs);
                        //xs.Serialize(writer, myXml);
                        //writer.Close();
                    }

                    //using (Stream fs = (Stream)this._SaveDiag.OpenFile())
                    //{
                    // fs.Write(fileBytes, 0, fileBytes.Length);
                    //} 
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error : " + ex.ToString());
                }
            }
        }

        private void btnImport_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                InitImportDialog();
                // Show dialog                
                if (_ImportDiag.ShowDialog() == true)
                {
                    // Get the selected file name and set it as text of a TextBox
                    xdocImport = XDocument.Load(_ImportDiag.File.OpenText());
                    LoadXMLToGrid();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("btnImport_Click Error : " + ex.ToString());
            }
        }

        private void LoadXMLToGrid()
        {
            _UsersQueriesImport.Clear();
            _UsersQueriesImport = new List<UserQuery>();
            foreach (var userQueryElem in xdocImport.Root.Descendants("UserQuery"))
            {
                UserQuery u = new UserQuery();
                u.Name = userQueryElem.Element("Name").Value;
                u.Description = userQueryElem.Element("Description").Value;
                u.FetchXml = userQueryElem.Element("FetchXml").Value;
                u.ColumnSetXml = userQueryElem.Element("ColumnSetXml").Value;
                u.AdvancedGroupBy = userQueryElem.Element("AdvancedGroupBy").Value;
                u.ConditionalFormatting = userQueryElem.Element("ConditionalFormatting").Value;
                u.LayoutXml = userQueryElem.Element("LayoutXml").Value;
                u.ReturnedTypeCode = userQueryElem.Element("ReturnedTypeCode").Value;
                if (!String.IsNullOrEmpty(userQueryElem.Element("QueryType").Value))
                {
                    u.QueryType = Convert.ToInt32(userQueryElem.Element("QueryType").Value);
                }
                if (!String.IsNullOrEmpty(userQueryElem.Element("VersionNumber").Value))
                {
                    u.VersionNumber = Convert.ToInt64(userQueryElem.Element("VersionNumber").Value);
                }
                _UsersQueriesImport.Add(u);
            }
            //var XmlData = from userQuery in xdoc.Descendants("UserQuery")
            //              select new UserQuery
            //              {
            //                  Name = userQuery.Element("Name").Value,
            //                  Description = userQuery.Element("Description").Value,
            //                  FetchXml = userQuery.Element("FetchXml").Value,
            //                  ColumnSetXml = userQuery.Element("ColumnSetXml").Value,
            //                  AdvancedGroupBy = userQuery.Element("AdvancedGroupBy").Value,
            //                  ConditionalFormatting = userQuery.Element("ConditionalFormatting").Value,
            //                  LayoutXml = userQuery.Element("LayoutXml").Value,
            //                  QueryType = Convert.ToInt32(userQuery.Element("QueryType").Value),
            //                  ReturnedTypeCode = userQuery.Element("ReturnedTypeCode").Value,
            //                  VersionNumber = Convert.ToInt64(userQuery.Element("VersionNumber").Value)
            //              };
            dgUserQueriesImport.ItemsSource = _UsersQueriesImport;
        }

        private void btnImportToCRM_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                for (int i = 0; i < _UsersQueriesImport.Count(); i++)
                {
                    _context.AddToUserQuerySet(_UsersQueriesImport[i]);
                }
                _context.BeginSaveChanges(OnUserQueryCreateComplate, null);
                //foreach (UserQuery u in _UsersQueriesImport)
                //{
                //    //EntityReference entRef = new EntityReference();
                //    //entRef.Id = user.SystemUserId;
                //    //entRef.Name = user.FullName;
                //    //entRef.LogicalName = "SystemUser";
                //    //u.OwnerId = entRef;
                //    _context.AddToUserQuerySet(u);
                //    _context.BeginSaveChanges(OnUserQueryCreateComplate, u);
                //}
                MessageBox.Show(String.Format("{0} Saved Quries were created successfully", _UsersQueriesImport.Count()));
                LoadXMLToGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show("btnImportToCRM_Click Error : " + ex.ToString());
            }
        }

        public void OnUserQueryCreateComplate(IAsyncResult result)
        {
            try
            {
                _context.EndSaveChanges(result);
                //MessageBox.Show(((UserQuery)result.AsyncState).Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show("OnUserQueryCreateComplate Error : " + ex.ToString());
            }
        }

        private void btnRefresh_Click(object sender, RoutedEventArgs e)
        {
            LoadExistingUserQueries();
        }
    }
}
